package com.cskaoyan.gateway.controller.shopping;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
//import com.mall.promo.cache.CacheManager;
import com.cskaoyan.gateway.config.CacheManager;
import com.google.common.util.concurrent.RateLimiter;
import com.mall.commons.result.ResponseData;
import com.mall.commons.result.ResponseUtil;
import com.mall.promo.PromoService;
import com.mall.promo.constant.PromoRetCode;
import com.mall.promo.dto.*;
import com.mall.shopping.IContentService;
import com.mall.shopping.IHomeService;
import com.mall.shopping.IProductCateService;
import com.mall.shopping.IProductService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.dto.*;
import com.mall.user.IUserQueryService;
import com.mall.user.annotation.Anoymous;
import com.mall.user.intercepter.TokenIntercepter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;


/**
 * @Time : 2021/8/25 16:18
 * @Author : Xfeng
 */

@Slf4j
@RestController
@RequestMapping("shopping")
@Api(tags = "GoodsController", description = "商品显示层")
public class GoodsController {

    @Reference(timeout = 20000,check = false)
    private IHomeService iHomeService;

    @Reference(timeout = 20000,check = false)
    private IContentService iContentService;

    @Reference(timeout = 20000,check = false)
    private IProductCateService iProductCateService;

    @Reference(timeout = 20000,check = false)
    private IProductService iProductService;

    @Reference(timeout = 20000,check = false)
    private PromoService promoService;

    @Reference(timeout = 20000,check = false)
    private IUserQueryService iUserQueryService;

    @Autowired
    CacheManager cacheManager;

    RateLimiter rateLimiter;

    ExecutorService executorService;

    @PostConstruct
    public void init(){
        //创建一个每秒产生100个令牌的令牌桶
        rateLimiter = RateLimiter.create(100);

        executorService = Executors.newFixedThreadPool(100);
    }

    @GetMapping("homepage")
    @ApiOperation("主页显示")
    @Anoymous
    public ResponseData homepage() {
        HomePageResponse response = iHomeService.homepage();

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response.getPanelContentItemDtos());
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());

    }

    @GetMapping("navigation")
    @ApiOperation("导航栏显示")
    @Anoymous
    public ResponseData navigation() {
        NavListResponse response = iContentService.queryNavList();

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response.getPannelContentDtos());
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());

    }

    @GetMapping("categories")
    @ApiOperation("列举所有商品种类")
    @Anoymous
    public ResponseData categories(AllProductCateRequest request) {
        AllProductCateResponse response = iProductCateService.getAllProductCate(request);

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response.getProductCateDtoList());
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

    @GetMapping("product/{id}")
    @ApiOperation("查看商品详情")
    @Anoymous
    public ResponseData product(@PathVariable("id")Long id) {
        ProductDetailRequest request = new ProductDetailRequest();
        request.setId(id);
        ProductDetailResponse response = iProductService.getProductDetail(request);

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response.getProductDetailDto());
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

    @GetMapping("goods")
    @ApiOperation("分页查询商品列表")
    @Anoymous
    public ResponseData goods(AllProductRequest request) {

        AllProductResponse response = iProductService.getAllProduct(request);

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            response.setCode(null);
            response.setMsg(null);
            return new ResponseUtil().setData(response);
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

    @GetMapping("recommend")
    @ApiOperation("查询推荐商品")
    @Anoymous
    public ResponseData recommend() {

        RecommendResponse response = iProductService.getRecommendGoods();

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response.getPanelContentItemDtos());
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

    @GetMapping("seckilllist")
    @ApiOperation("秒杀活动")
    @Anoymous
    public ResponseData seckilllist(Integer sessionId) {
        PromoInfoRequest promoInfoRequest = new PromoInfoRequest();
        promoInfoRequest.setSessionId(sessionId);
        String format = new SimpleDateFormat("yyyyMMdd").format(new Date());
        promoInfoRequest.setYyyymmdd(format);

        PromoInfoResponse response = promoService.getPromoList(promoInfoRequest);

        if (response.getCode().equals(PromoRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response);
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());

    }

    @PostMapping("promoProductDetail")
    @ApiOperation("获取秒杀商品详情")
    public ResponseData promoProductDetail(@RequestBody PromoProductDetailRequest request) {

        PromoProductDetailResponse response = promoService.getPromoProductDetail(request);

        if (response.getCode().equals(PromoRetCode.SUCCESS.getCode())) {
            return new ResponseUtil().setData(response);
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());

    }

    @PostMapping("seckill")
    @ApiOperation("秒杀下单")
    public ResponseData seckill(@RequestBody CreatePromoOrderRequest request, HttpServletRequest servletRequest) {

        //限制涌入系统的请求数量
        rateLimiter.acquire();

        Long psId = request.getPsId();
        Long productId = request.getProductId();
        String stockNotEnoughKey = "promo_item_stock" + productId + "-" + psId;

        String s = cacheManager.checkCache(stockNotEnoughKey);
        if(s != null && s.equals("none")){
            return new ResponseUtil().setErrorMsg(PromoRetCode.PROMO_ORDER_FAILED.getMessage());
        }

        //从TokenInterceptor设置的request域中取出当前登录的userId
        String userInfo = (String) servletRequest.getAttribute(TokenIntercepter.USER_INFO_KEY);
        //Json字符串转换为Json对象
        JSONObject object = JSON.parseObject(userInfo);
        long userId = Long.parseLong(object.get("uid").toString());

        String username = iUserQueryService.queryUser(userId);
        request.setUserId(userId);
        request.setUsername(username);


        //限制下游服务同时处理的请求数量
        Future<CreatePromoOrderResponse> future = executorService.submit(new Callable<CreatePromoOrderResponse>() {
            @Override
            public CreatePromoOrderResponse call() throws Exception {
                return promoService.createPromoOrderInTransaction(request);
            }
        });

        CreatePromoOrderResponse response = null;
        try {
            response = future.get();
            if (response.getCode().equals(PromoRetCode.SUCCESS.getCode())) {
                return new ResponseUtil().setData(response);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

    @PostMapping("search")
    @ApiOperation("查询商品")
    @Anoymous
    public ResponseData search(@RequestBody AllProductRequest request) {

        AllProductResponse response = iProductService.getAllProduct(request);

        if (response.getCode().equals(ShoppingRetCode.SUCCESS.getCode())) {
            response.setCode(null);
            response.setMsg(null);
            return new ResponseUtil().setData(response);
        }
        return new ResponseUtil().setErrorMsg(response.getMsg());
    }

}
